package slsLog

import (
	"encoding/json"
	"fmt"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/config"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/toolfunc"
	"math/rand"
	"time"

	sls "github.com/aliyun/aliyun-log-go-sdk"
	"github.com/gogo/protobuf/proto"
)

var (
	ProjectName      = "teams-api"
	AccessKeyID      = config.C.Oss.AccessKeyId
	AccessKeySecret  = config.C.Oss.AccessKeySecret
	Endpoint         = "cn-zhangjiakou.log.aliyuncs.com" // just like cn-hangzhou.log.aliyuncs.com
	LogStoreName     = "api-log-store"
	Client           sls.ClientInterface
	envName          = "测试环境"
	logChan          chan []*sls.Log
	aliyunLogMaxByte = toolfunc.ToBytes(1, "MB")
)

// You can get the variable from the environment variable, or fill in the required configuration directly in the init function.
func init() {
	Client = sls.CreateNormalInterface(Endpoint, AccessKeyID, AccessKeySecret, "")
	if !config.C.Debug {
		envName = "生产环境"
	}
}
func DeleteLog(ProjectName, LogStoreName string) {
	fmt.Println("log begin")
	logstore_name := LogStoreName
	Client.DeleteLogStore(ProjectName, logstore_name)
}
func CreateLogStore(ProjectName, LogStoreName string) error {
	err := Client.CreateLogStore(ProjectName, LogStoreName, 1, 2, true, 16)
	if err != nil {
		fmt.Printf("CreateLogStore fail, err: %s", err)
		return err
	}
	return nil
}
func GetLogByQueryExp(ProjectName, LogStoreName, topic, QueryExp string, num, offset int64) error {
	logstore, err := Client.GetLogStore(ProjectName, LogStoreName)
	if err != nil {
		return err
	}
	fmt.Printf("GetLogStore success, name: %s, ttl: %d, shardCount: %d, createTime: %d, lastModifyTime: %d\n", logstore.Name, logstore.TTL, logstore.ShardCount, logstore.CreateTime, logstore.LastModifyTime)
	resp, err := logstore.GetLogs(topic, time.Now().Unix()-100000, time.Now().Unix(), QueryExp, num, offset, true)
	if err != nil {
		fmt.Println(err)
		return err
	}
	fmt.Println(resp)
	return nil
}
func CreatIndex(ProjectName, LogStoreName string) error {

	indexKeys := map[string]sls.IndexKey{
		"user_id": {
			Token:         []string{" "},
			CaseSensitive: false,
			Type:          "long",
		},
		"real_name": {
			Token:         []string{" "},
			CaseSensitive: false,
			Type:          "text",
		},
		"depart_name": {
			Token:         []string{" "},
			CaseSensitive: false,
			Type:          "text",
		},
		"ip": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"param": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"event": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"app_name": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"app_version": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"platform": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"device_id": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"device_name": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"nation": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"province": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"city": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"op_status": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"description": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
		"count": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "long",
		},
		"duration": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "double",
		},
		"token": {
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			Type:          "text",
		},
	}
	index := sls.Index{
		Keys: indexKeys,
		Line: &sls.IndexLine{
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			IncludeKeys:   []string{},
			ExcludeKeys:   []string{},
		},
	}
	err := Client.CreateIndex(ProjectName, LogStoreName, index)
	if err != nil {
		fmt.Printf("CreateIndex fail, err: %s", err)
		return err
	}
	fmt.Println("CreateIndex success")
	return nil
}

func PutLogs(ProjectName, LogStoreName, Ip, topic string, logs []*sls.Log) error {
	loggroup := &sls.LogGroup{
		Topic:  proto.String(topic),
		Source: proto.String(Ip),
		Logs:   logs,
	}
	// PutLogs API Ref: https://intl.aliyun.com/help/doc-detail/29026.htm
	logMax, _ := json.Marshal(loggroup)
	if int64(len(logMax)) >= aliyunLogMaxByte {
		fmt.Println("日志长度超出推送范围")
		return nil
	}

	err := Client.PutLogs(ProjectName, LogStoreName, loggroup)
	if err == nil {
		//fmt.Println("PutLogs success")
	} else {
		fmt.Printf("PutLogs fail, err: %s\n", err)
		return err
	}
	return nil
}
func GetHistograms(ProjectName, LogStoreName string) error {
	end_time := uint32(time.Now().Unix())
	// search logs from index on logstore
	totalCount := int64(0)
	begin_time := uint32(time.Now().Unix())
	rand.Seed(int64(begin_time))
	for {
		// GetHistograms API Ref: https://intl.aliyun.com/help/doc-detail/29030.htm
		ghResp, err := Client.GetHistograms(ProjectName, LogStoreName, "", int64(begin_time), int64(end_time), "col_0 > 1000000")
		if err != nil {
			fmt.Printf("GetHistograms fail, err: %v\n", err)
			time.Sleep(10 * time.Millisecond)
			continue
		}
		fmt.Printf("complete: %s, count: %d, histograms: %v\n", ghResp.Progress, ghResp.Count, ghResp.Histograms)
		totalCount += ghResp.Count
		if ghResp.Progress == "Complete" {
			break
		}
	}
	return nil
}

type SlsLogFormt struct {
	LogLevel   string `json:"logLevel"`
	LogContent any    `json:"logContent"`
}

//// 将运行日志写入 阿里云sls 中
//func (slsF SlsLogFormt) PrintLogToSls(nowTime int64) {
//	slsFByte, _ := json.Marshal(slsF)
//	var logs []*sls.Log
//	var content []*sls.LogContent
//	content = append(content, &sls.LogContent{
//		Key:   proto.String(fmt.Sprintf("content")),
//		Value: proto.String(string(slsFByte)),
//	})
//	slsLog := &sls.Log{
//		Time:     proto.Uint32(uint32(nowTime)),
//		Contents: content,
//	}
//	logs = append(logs, slsLog)
//	logsByte, _ := json.Marshal(logs)
//
//	//推送kafka
//	SendKafka(logsByte)
//}
//
//func SendKafka(logsByte []byte) {
//	msg := &sarama.ProducerMessage{}
//	msg.Topic = config.C.Service.Name
//	msg.Key = sarama.StringEncoder(config.C.Service.Name + "_" + envName)
//	msg.Value = sarama.ByteEncoder(logsByte)
//	if _, _, err := kafka.KafkaProduct.SendMessage(msg); err != nil {
//		fmt.Errorf("消息写入消息队列失败，err:%v", err.Error())
//	}
//	kafka.KafkaProduct.SendMessage(msg)
//}
